package com.yikun.springbootinit.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yikun.springbootinit.common.ErrorCode;
import com.yikun.springbootinit.datasource.*;
import com.yikun.springbootinit.exception.BusinessException;
import com.yikun.springbootinit.exception.ThrowUtils;
import com.yikun.springbootinit.model.dto.search.SearchRequest;
import com.yikun.springbootinit.model.entity.Picture;
import com.yikun.springbootinit.model.enums.SearchTypeEnum;
import com.yikun.springbootinit.model.vo.PostVO;
import com.yikun.springbootinit.model.vo.SearchVO;
import com.yikun.springbootinit.model.vo.UserVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.*;

/**
 * <h1>搜索门面<h1>
 *
 * @ClassName: SearchFacade
 * @Author: 初久
 * @Date: 2023/4/5 20:01
 **/
@Component
public class SearchFacade {

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private UserDataSource userDataSource;

    @Resource
    private PictureDataSource pictureDataSource;

    @Resource
    private DataSourceRegistry dataSourceRegistry;

    /**
     * 自定义线程池
     */
    private static final ThreadPoolExecutor SEARCH_TASK_EXECUTOR = new ThreadPoolExecutor(
            30, 60,
            60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(60),
            Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()
    );


    public SearchVO searchAll(@RequestBody SearchRequest searchRequest, HttpServletRequest request) {

        String type = searchRequest.getType();
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        // 判断参数是否为空数
        ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);

        String searchText = searchRequest.getSearchText();
        long current = searchRequest.getCurrent();
        long pageSize = searchRequest.getPageSize();
        SearchVO searchVO = new SearchVO();

        // 类型为空，查询所有类型的数据
        if (null == searchTypeEnum) {

            // 闭锁
            CountDownLatch countDownLatch = new CountDownLatch(3);

            SEARCH_TASK_EXECUTOR.execute(() -> {

                Page<Picture> picturePage = pictureDataSource.doSearch(searchText, 1, 10);
                searchVO.setPictureList(picturePage.getRecords());

                countDownLatch.countDown();
            });

            SEARCH_TASK_EXECUTOR.execute(() -> {

                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                searchVO.setUserList(userVOPage.getRecords());

                countDownLatch.countDown();
            });

            SEARCH_TASK_EXECUTOR.execute(() -> {

                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                searchVO.setPostList(postVOPage.getRecords());

                countDownLatch.countDown();
            });


            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "异步搜索任务执行失败");
            }


        } else {

            // 根据value值获取对应的实例bean
            DataSource<?> dataSource = dataSourceRegistry.getDataSourceByType(type);

            // 查询该类型数据
            Page<?> page = dataSource.doSearch(searchText, current, pageSize);

            searchVO.setDataList(page.getRecords());

        }

        return searchVO;
    }

}
